<template>
  <div class="app-container">
    <div class="filter-container">
      <el-row :gutter="80">
        <el-col :span="4">
          <el-card
            :style="{height:screenHeight+'px'}"
            class="box-card friends-box"
            shadow="hover"
            style="height:100px;overflow:auto"
          >
            <div slot="header" class="clearfix">
              <span>好友列表</span>
              <el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button>
            </div>
            <div v-for="item in AllFriends" :key="item.id" style="margin-top: 10px">
              <el-button class="friends-font" @click="selectUser = item">{{ item.showName }}&nbsp;&nbsp;&nbsp;<i
                class="el-icon-bell"
              /></el-button>
            </div>
          </el-card>
        </el-col>
        <el-col :span="20">
          <el-card :style="{height:screenHeight+'px'}" class="box-card chat-box" shadow="hover">
            <div slot="header" class="clearfix" style="text-align: center">
              <span><font style="font-size: 20px">聊天室</font>{{
                selectUser.showName === undefined ? '' : '(' + selectUser.showName + ')'
              }}</span>
            </div>
            <div :style="{height:screenHeight-340 +'px'}">
              <div style="overflow:auto;width: 100%;max-height: 90% " v-html="content" />
            </div>
            <div>
              <el-divider content-position="center">开始愉快的聊天吧</el-divider>
              <div>
                <el-input
                  v-model="chatTxt"
                  :autosize="{ minRows: 6, maxRows: 20}"
                  placeholder="请输入聊天内容"
                  type="textarea"
                />
              </div>
              <div style="text-align: center;margin-top: 20px">
                <el-button
                  icon="el-icon-position"
                  type="primary"
                  @click.native.prevent="sendMsg"
                >发送
                </el-button>
                <el-button icon="el-icon-refresh-left" type="success" @click="chatTxt = ''">清空</el-button>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>
  </div>
</template>
<script>

import { mapGetters } from 'vuex'

export default {
  data() {
    return {
      screenHeight: '',
      chatTxt: '',
      webUrl: '',
      content: '',
      webSocket: null,
      heartBeat: null,
      lockReconnect: false,
      selectUser: {},
      message: {},
      timeout: 5 * 1000 // 5秒一次心跳
    }
  },
  computed: {
    ...mapGetters([
      'avatar',
      'token',
      'userId',
      'hasLogin',
      'friends'
    ]),
    AllFriends() {
      return this.friends.filter((item, index, self) => {
        return self.findIndex(t => JSON.stringify(t) === JSON.stringify(item)) === index
      }).filter(item => {
        return item.id !== this.userId
      })
    }
  },
  watch: {
    hasLogin: function(newVal, oldVal) {
      console.log(newVal)
      if (newVal) {
        this.initWebSocket()
      } else {
        this.webSocketClose()
      }
    }
  },
  mounted() {
    this.screenHeight = document.body.clientHeight - 200
    this.webUrl = process.env.NODE_ENV === 'development' ? 'ws://localhost:9999/webSocket/' : 'ws://47.106.201.146:9999/webSocket/'
    this.initWebSocket()
  },
  methods: {
    initWebSocket() {
      const url = this.webUrl + this.token
      if (typeof (WebSocket) === 'undefined') {
        console.log('您的浏览器不支持WebSocket')
      } else {
        console.log('您的浏览器支持WebSocket')
        this.webSocket = new WebSocket(url)
        this.webSocket.onopen = this.webSocketOpen
        this.webSocket.onclose = this.webSocketClose
        this.webSocket.onerror = this.webSocketOnError
        this.webSocket.onmessage = this.webSocketOnMessage
        this.startHeartBeat()
      }
    },
    webSocketOpen() {
      console.log('WebSocket建立连接')
      this.webSocket.send(JSON.stringify({ 'type': 'heartBeat' }))
    },
    webSocketClose() {
      console.log('WebSocket连接关闭')
      this.$store.dispatch('removeFriends', this.userId)
      this.webSocket.onClose()
      this.startHeartBeat()
    },
    webSocketOnError(err) {
      console.log('onerror')
      console.log(err)
      this.webSocket.onError()
      this.startHeartBeat()
    },
    webSocketOnMessage(res) {
      const data = JSON.parse(res.data)
      if (data && data.type === 'heartBeat') {
        // 心跳重置
        this.resetHeartBeat()
      } else if (data.type === 'chat') {
        this.selectUser = data.user
        this.createContent(data)
        console.log(data)
      } else if (data.type === 'online') {
        this.$store.dispatch('setFriends', data.user)
      }
    },
    startHeartBeat() {
      console.log('重置并启动心跳')
      this.heartBeat && clearTimeout(this.heartBeat)
      this.heartBeat = setTimeout(() => {
        // 发送一个心跳，后端收到后返回一个心跳消息
        if (this.webSocket && this.webSocket.readyState === 1) {
          console.log('主动发送心跳')
          this.webSocket.send(JSON.stringify({ 'type': 'heartBeat' }))
        } else {
          this.reconnect()
        }
      }, this.timeout)
    },
    reconnect() {
      console.log('重新连接')
      if (this.lockReconnect) {
        return false
      }
      this.lockReconnect = true
      this.initWebSocket()
      this.lockReconnect = false
    },
    resetHeartBeat() {
      clearTimeout(this.heartBeat)
      // 重启心跳
      this.startHeartBeat()
    },
    sendMsg() {
      if (this.selectUser.id === undefined) {
        this.$message.error('未选择聊天对象')
        return
      }
      if (this.chatTxt === '') {
        return
      }
      // 聊天数据对象
      this.message = {
        'type': 'chat',
        'message': this.chatTxt,
        'fromUserId': this.userId,
        'toUserId': this.selectUser.id
      }
      this.webSocket.send(JSON.stringify(this.message))
      this.chatTxt = ''
    },
    createContent(data) {
      console.log('开始拼装消息')
      let html
      if (data.fromUserId === this.userId) {
        const img = this.avatar + '?imageView2/1/w/80/h/80'
        // 当前用户发的消息
        html = '<div class="el-row" style="padding:5px 0">' +
          '<div class="el-col el-col-22" style="text-align: right;padding-right: 10px">' +
          '<div class="tip left">' + data.message + '</div>' +
          '</div>' +
          '<div  class="el-col el-col-1">' +
          '<span class="el-avatar el-avatar--circle" style="height: 40px;width: 40px;line-height: 40px">' +
          '<img src=' + img + ' style="object-fit: cover">' +
          '</span>' +
          '</div>' +
          '</div>'
      } else {
        const img = 'https://ui-avatars.com/api/?background=1890ff&color=fff&name=' + data.user.loginName
        // 其他用户发的消息
        html = '<div class="el-row" style="padding:5px 0">' +
          '<div class="el-col el-col-1">' +
          '<span class="el-avatar el-avatar--circle" style="height: 40px;width: 40px;line-height: 40px">' +
          '<img src=' + img + ' style="object-fit: cover">' +
          '</span>' +
          '</div>' +
          '<div  class="el-col el-col-22" style="text-align: left;padding-left: 10px">' +
          '<div class="tip right">' + data.message + '</div>' +
          '</div>' +
          '</div>'
      }
      console.log(html)
      this.content += html
    }
  }
}
</script>
<style>
.el-form .el-select {
  width: 100%;
}

.box {
  height: 100%;
  overflow: auto;
}

.tip {
  color: white;
  text-align: center;
  border-radius: 10px;
  font-family: sans-serif;
  padding: 10px;
  width: auto;
  display: inline;
  display: inline-block !important;
}

.right {
  background-color: deepskyblue;
}

.left {
  background-color: forestgreen;
}

.friends-font {
  font-size: 16px;
  width: 100%;
  color: #000000;
}

</style>
